package cn.mdmbct.douyin.common.executor;

import cn.mdmbct.douyin.common.bean.AccessToken;
import cn.mdmbct.douyin.common.bean.RefreshToken;
import cn.mdmbct.douyin.common.enums.ApiPlatform;
import cn.mdmbct.douyin.common.exception.ApiCallException;
import cn.mdmbct.douyin.common.exception.LandExpirationException;
import cn.mdmbct.douyin.common.response.auth.AccessTokenRes;
import cn.mdmbct.douyin.common.response.auth.RenewRefreshTokenRes;
import cn.mdmbct.douyin.common.session.DySession;
import lombok.extern.slf4j.Slf4j;

/**
 * @author mdmbct  mdmbct@outlook.com
 * @date 5/10/2021 21:18 AM
 * @modified mdmbct
 * @since 1.0
 */
@Slf4j
public class DefaultTokenManager implements DyTokenManager {


    private final DySession storageManager;

    private final DyAuthService dyAuthService;

    public DefaultTokenManager(DySession dySession) {
        this.storageManager = dySession;
        this.dyAuthService = new DyAuthService(dySession);
    }

    @Override
    public AccessToken getAccessToken(String openId, ApiPlatform apiPlatform, boolean autoRenew) throws LandExpirationException {
        AccessToken accessToken = storageManager.getAccessToken(openId);
        if (accessToken != null) {
            return accessToken;
        }
        if (autoRenew) {
            // 刷新AccessToken需要RefreshToken
            // 如果RefreshToken不存在的话 getRefreshToken中会抛出LandExpirationException 需要重新走授权的流程
            RefreshToken refreshToken = getRefreshToken(openId);
            // 拿RefreshToken获取AccessToken
            return renewAccessToken(refreshToken, apiPlatform);
        }
        return null;
    }

    @Override
    public AccessToken renewAccessToken(RefreshToken refreshToken, ApiPlatform apiPlatform) throws ApiCallException {
        AccessTokenRes.AccessTokenResData accessTokenResData = dyAuthService.requestAccessTokenByRefreshToken(refreshToken, apiPlatform);
        return new AccessToken(System.currentTimeMillis(), accessTokenResData.getExpiresIn() * 1000L, accessTokenResData.getAccessToken());
    }

    @Override
    public RefreshToken getRefreshToken(String openId) throws LandExpirationException {
        RefreshToken refreshToken = storageManager.getRefreshToken(openId);
        if (refreshToken == null) {
            log.error(LandExpirationException.DEFAULT_MSG);
            throw new LandExpirationException();
        }
        return refreshToken;
    }

    @Override
    public RefreshToken renewRefreshToken(RefreshToken oldRefreshToken, String openId) throws ApiCallException {
        RenewRefreshTokenRes.RenewRefreshTokenResData data = dyAuthService.requestRefreshTokenByOld(oldRefreshToken, openId);
        return new RefreshToken(System.currentTimeMillis(), data.getExpiresIn() * 1000L, data.getRefreshToken());
    }
}
